home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 03 - 1987 / 03.09 Sep 87 / shift mod source / shiftMod.c next >
Encoding:
C/C++ Source or Header  |  1987-07-27  |  2.5 KB  |  113 lines  |  [TEXT/KAHL]

  1. /* shiftMod.c    2 July 1987
  2.  *
  3.  * by Mike Scanlin and Andy Voelker
  4.  *
  5.  * Installs a tail patch on _GetNextEvent so that the Shift key toggles
  6.  * between upper and lower case letters if the Caps Lock key is down.
  7.  *
  8.  * No toggle is done if the option and/or command key was held down.
  9.  *
  10.  */
  11.  
  12. #include "Asm.h"
  13. #include "EventMgr.h"
  14.  
  15. #define    what            OFFSET(EventRecord,what)
  16. #define message            OFFSET(EventRecord,message)
  17. #define    modifiers        OFFSET(EventRecord,modifiers)
  18.  
  19. #define    GetNextEvent    0xA970
  20. #define JMP                0x4EF9
  21. #define memFullErr        -108
  22.  
  23. void    main(void); /* prototype for main() */
  24.  
  25. void    main()
  26. {
  27.     asm    {
  28.                 move.l    D3,-(SP)
  29.                 
  30. /* set up the JMP instruction at the end of the patch */
  31.                 lea        @patchExit,A0
  32.                 move    #JMP,(A0)
  33.  
  34. /* get the old trap address */    
  35.                 move    #GetNextEvent,D0
  36.                 _GetTrapAddress
  37.                 
  38. /* set up the JMP instruction that calls the original trap */
  39.                 lea        @origTrap,A1
  40.                 move    #JMP,(A1)+
  41.                 move.l    A0,(A1)
  42.  
  43. /* get some space in the system heap */
  44.                 lea        @last,A0
  45.                 lea        @first,A1
  46.                 suba.l    A1,A0
  47.                 move.l    A0,D0
  48.                 move.l    D0,D3        /* save for _BlockMove */
  49.                 _NewPtr    SYS
  50.                 cmpi    #memFullErr,D0
  51.                 beq.s    @noPatch
  52.                 move.l    A0,-(SP)    /* save for _BlockMove */
  53.  
  54. /* set the trap address to the space we just got in the system heap. */
  55.                 move    #GetNextEvent,D0
  56.                 _SetTrapAddress
  57.                 
  58. /* now move it into place */    
  59.                 lea        @first,A0        
  60.                 move.l    (SP)+,A1
  61.                 move.l    D3,D0
  62.                 _BlockMove
  63.                 
  64. @noPatch        move.l    (SP)+,D3
  65.                 rts
  66.  
  67.  
  68. /*
  69.  * Here's the new _GetNextEvent. It calls the existing _GetNextEvent
  70.  * and then checks if a keyDown or autoKey event is being reported.
  71.  */
  72.  
  73. @first            lea        @exitAddress,A0
  74.                 move.l    (SP)+,(A0)        /* save original return address */
  75.                 lea        @eventPtr,A0
  76.                 move.l    (SP),(A0)        /* save ptr to event record */
  77.                 pea        @tailPatch        /* return to our routine */
  78.  
  79. @origTrap        nop                        /* JMP to original trap */
  80.                 nop
  81.                 nop
  82.         
  83. @tailPatch        lea        @eventPtr,A0
  84.                 move.l    (A0),A0
  85.  
  86.                 move    what(A0),D0        /* is it a keyDown or autoKey? */
  87.                 cmpi    #keyDown,D0
  88.                 beq.s    @isKeyDown
  89.                 cmpi    #autoKey,D0
  90.                 bne.s    @patchExit
  91.  
  92. @isKeyDown        move    modifiers(A0),D0
  93.                 andi    #shiftKey+alphaLock+optionKey+cmdKey,D0
  94.                 eori    #shiftKey+alphaLock,D0
  95.                 bne.s    @patchExit
  96.  
  97.                 move.l    message(A0),D0
  98.                 cmpi.b     #'A',D0
  99.                 bmi.s    @patchExit
  100.                 cmpi.b    #'Z',D0
  101.                 bgt.s    @patchExit
  102.                 addi.b    #'a'-'A',D0
  103.                 move.l    D0,message(A0)
  104.  
  105. @patchExit        nop            /* return to original caller via long JMP */
  106. @exitAddress    nop
  107.                 nop
  108.  
  109. @eventPtr        dc.l    0        /* storage for event record ptr */
  110.  
  111. @last
  112.     }
  113. }